home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / game / shoot / ADescentSrc.lha / descent / Amiga / JoyDriv.c < prev    next >
C/C++ Source or Header  |  1998-03-14  |  10KB  |  370 lines

  1. /*********************************************************/
  2. /*                                                       */
  3. /* Copyright (c) 1989, David Kinzer, All Rights Reserved */
  4. /*                                                       */
  5. /* Permission hereby granted to redistribute this        */
  6. /* program in unmodified form in a not for profit manner.*/
  7. /*                                                       */
  8. /* Permission hereby granted to use this software freely */
  9. /* in programs, commercial or not.                       */
  10. /*                                                       */
  11. /*********************************************************/
  12. /*                                                       */
  13. /* JoyDriv.c                                             */
  14. /*                                                       */
  15. /* Analog joystick interface routines                    */
  16. /*                                                       */
  17. /* This file contains the routines needed to interface   */
  18. /* to an analog joystick.  The routines supplied will    */
  19. /* open, read, and close an analog joystick port.        */
  20. /* Note that in order to use joyport 0 (left mouse port) */
  21. /* the intuition interface will have to be turned off.   */
  22. /*                                                       */
  23. /*********************************************************/
  24.  
  25. #include "exec/types.h"
  26. #include "exec/memory.h"
  27. #include "exec/interrupts.h"
  28. #include "hardware/custom.h"
  29. #include "hardware/intbits.h"
  30.  
  31. #include <stdio.h>
  32.  
  33. #include "AJoystick.h"
  34.  
  35. #define POTBITS0        0x0F01
  36. #define POTBITS1        0xF001
  37. #define INPUT0          0x0000
  38. #define INPUT1          0x0000
  39. #define INMASK0         0x0A00
  40. #define INMASK1         0xA000
  41.  
  42.  
  43.  
  44.  
  45. struct joydata {
  46.    struct {
  47.       unsigned short x;
  48.       unsigned short y;
  49.       char b1;
  50.       char b2;
  51.       char b3;
  52.       char b4;
  53.       char eb1;
  54.       char eb2;
  55.       char eb3;
  56.       char eb4;
  57.    } unit0,unit1;
  58.    APTR pgbase;
  59.    long unitflags;
  60. };
  61.  
  62.  
  63.  
  64.  
  65. APTR PotgoBase = 0;               /* Library base        */
  66. long gotpotgo = 0;                /* Potgo register bits */
  67.                                   /*  we are using       */
  68. struct joydata *JoyData = NULL;   /* Pointer to data     */
  69.                                   /*  passing area       */
  70. struct Interrupt *VBRData = NULL; /* Pointer to VERTB    */
  71.                                   /*  interrupt node     */
  72. extern VOID vbserver();
  73.  
  74.  
  75. /* Open Analog Joystick Routine */
  76.  
  77. struct joydata *OpenAJoystick(long units)
  78. {
  79. long wantpotgo, AllocPotBits();
  80. long inputbits, inputmask;
  81. APTR OpenResource(), AllocMem();
  82.  
  83.  
  84.    /* reject open if already opened. */
  85.  
  86.     #ifdef JOY_DEBUG
  87.     printf("sizeof(struct joydata)=%d\n", sizeof(struct joydata));
  88.     #endif
  89.  
  90.    if (JoyData) {
  91.       return NULL;
  92.    }
  93.  
  94.    /* Open potgo resource.  The resource controls        */
  95.    /* allocation and writing of the potgo register.      */
  96.    /* Note: There is no corresponding CloseResource call */
  97.    /*       in the Amiga.                                */
  98.  
  99.    PotgoBase = OpenResource((STRPTR)"potgo.resource");
  100.    if (!PotgoBase) {
  101.       return NULL;    /* Return error if potgo.resource */
  102.                       /* is not available.              */
  103.    }
  104.  
  105.    #ifdef JOY_DEBUG
  106.     printf("Opened potgo.resource\n");
  107.    #endif
  108.  
  109.    /* figure out which bits we need */
  110.  
  111.    wantpotgo = 0;
  112.    inputbits = 0;
  113.    inputmask = 0;
  114.  
  115.    if (units & AJOYUNIT0) {
  116.       wantpotgo |= POTBITS0;
  117.       inputbits |= INPUT0;
  118.       inputmask |= INMASK0;
  119.    }
  120.  
  121.    if (units & AJOYUNIT1) {
  122.       wantpotgo |= POTBITS1;
  123.       inputbits |= INPUT1;
  124.       inputmask |= INMASK1;
  125.    }
  126.  
  127.    /* Do we want anything?  If not, return error, since */
  128.    /* there is probably an error in the call.           */
  129.  
  130.    if (!wantpotgo) {
  131.       return NULL;
  132.    }
  133.  
  134.  
  135.    /* Allocate the bits that we need from the potgo  */
  136.    /* resource.                                      */
  137.  
  138.     /* HACK ALERT !!!!! */
  139.     //FreePotBits(0xFF00);
  140.  
  141.    gotpotgo = AllocPotBits(wantpotgo);
  142.  
  143.     #ifdef JOY_DEBUG
  144.     printf("Wanted potgo 0x%X, got 0x%X\n", wantpotgo, gotpotgo);
  145.     #endif
  146.  
  147.    /* See if we got what we needed. If not, return error */
  148.  
  149.    if (wantpotgo != gotpotgo) {
  150.       printf("Wanted 0x%X, but got 0x%X\n", wantpotgo, gotpotgo);
  151.       FreePotBits(gotpotgo); /* give back allocated bits */
  152.       return NULL;
  153.    }
  154.  
  155.  
  156.    /* Since we don't know what the hardware was set to   */
  157.    /* before we got it, we shall set the analog joystick */
  158.    /* bits to inputs like we want.                       */
  159.  
  160.    WritePotgo(inputbits,inputmask);
  161.  
  162.    /* Now that we have the hardware, we shall set up our */
  163.    /* VERTB (vertical blanking) interrupt server routine.*/
  164.    /* We get some Public memory for a shared data area   */
  165.    /* between the server and the ReadAJoystick routine.  */
  166.    /* Then we set up an interrupt structure which allows */
  167.    /* our server to become a part of the Amiga operating */
  168.    /* system.                                            */
  169.  
  170.    JoyData = (struct joydata *)AllocMem((long)sizeof
  171.                (struct joydata),MEMF_PUBLIC);
  172.    if (!JoyData) {       /* error if we can't get memory */
  173.       FreePotBits(gotpotgo); /* give back allocated bits */
  174.       return NULL;
  175.    }
  176.  
  177.    JoyData->pgbase = PotgoBase;     /* send potgobase to */
  178.                                     /*  vertb server     */
  179.    JoyData->unitflags = units;      /* send units to     */
  180.                                     /*  vertb server     */
  181.  
  182.    JoyData->unit0.x = 0x8000;       /* fill in some      */
  183.    JoyData->unit0.y = 0x8000;       /*  dummy values     */
  184.    JoyData->unit0.b1 = 0;
  185.    JoyData->unit0.b2 = 0;
  186.    JoyData->unit0.b3 = 0;
  187.    JoyData->unit0.b4 = 0;
  188.    JoyData->unit0.eb1 = 0;
  189.    JoyData->unit0.eb2 = 0;
  190.    JoyData->unit0.eb3 = 0;
  191.    JoyData->unit0.eb4 = 0;
  192.    JoyData->unit1.x = 0x8000;       
  193.    JoyData->unit1.y = 0x8000;
  194.    JoyData->unit1.b1 = 0;
  195.    JoyData->unit1.b2 = 0;
  196.    JoyData->unit1.b3 = 0;
  197.    JoyData->unit1.b4 = 0;
  198.    JoyData->unit1.eb1 = 0;
  199.    JoyData->unit1.eb2 = 0;
  200.    JoyData->unit1.eb3 = 0;
  201.    JoyData->unit1.eb4 = 0;
  202.  
  203.    VBRData = (struct Interrupt *)AllocMem((long)sizeof
  204.                 (struct Interrupt),MEMF_PUBLIC);
  205.    if (!VBRData) {       /* error if we can't get memory */
  206.       /* give back memory and allocated potgo bits */
  207.       FreeMem(JoyData,(long)sizeof(struct joydata));
  208.       FreePotBits(gotpotgo);        
  209.       return NULL;
  210.    }
  211.  
  212.  
  213.    /* Fill in the blanks of the Interrupt structure */
  214.  
  215.    VBRData->is_Node.ln_Type = NT_INTERRUPT;
  216.    VBRData->is_Node.ln_Pri = 10;
  217.    VBRData->is_Node.ln_Name = "VERTB for Analog Joystick";
  218.    VBRData->is_Data = (APTR)JoyData;
  219.    VBRData->is_Code = vbserver;
  220.  
  221.    /* And, finally, add interrupt routine to Operating  */
  222.    /* System.                                           */
  223.  
  224.    AddIntServer(INTB_VERTB,VBRData);
  225.  
  226.    /* Return pointer to data, in case user wants to go  */
  227.    /* directly to the data structures.                  */
  228.  
  229.     #ifdef JOY_DEBUG
  230.     printf("Joysticks set up\n");
  231.     #endif
  232.  
  233.    return JoyData;
  234.  
  235. }
  236.  
  237.  
  238. /* Close Analog Joystick routine.                       */
  239. /* Note: Since the Units are closely intertwined, I     */
  240. /*       decided to close all open units with one call. */
  241. /*       (since you had to open them with one call      */
  242. /*       anyway).                                       */
  243.  
  244. long CloseAJoystick(void)
  245. {
  246.  
  247.    /* Are we actually open? Error if not */
  248.  
  249.    if (!JoyData) {
  250.       return 0;
  251.    }
  252.  
  253.    /* Shut off VERTB routine */
  254.  
  255.    RemIntServer(INTB_VERTB,VBRData);
  256.  
  257.    /* Free up memory */
  258.  
  259.    FreeMem(JoyData,(long)sizeof(struct joydata));  
  260.    FreeMem(VBRData,(long)sizeof(struct Interrupt)); 
  261.  
  262.    /* Give back allocated potgo bits */
  263.  
  264.     #ifdef JOY_DEBUG
  265.     printf("Freeing potgo 0x%X\n", gotpotgo);
  266.     #endif
  267.  
  268.    FreePotBits(gotpotgo);
  269.  
  270.    /* Set Flag so we don't read bad data */
  271.  
  272.    JoyData = NULL;
  273.  
  274.    /* return success */
  275.  
  276.    return 1;
  277. }
  278.  
  279.  
  280. /* Joystick Read routine                                 */
  281. /* Note: Reads values left by last VERTB interrupt.      */
  282. /* Note: Data is stale until first interrupt comes along.*/
  283. /* Note: Only one Unit can be read at a time.            */
  284.  
  285. struct AJoyData *ReadAJoystick(long unit,struct AJoyData *UserDataPtr)
  286. {
  287.  
  288.    /* Are we open? Error if not. */
  289.  
  290.    if (!JoyData) {
  291.       return NULL;
  292.    }
  293.  
  294.    /* Is this unit open? Error if not */
  295.  
  296.    if (!(JoyData->unitflags & unit)) {
  297.       return NULL;
  298.    }
  299.  
  300.    /* Get data for unit and place in requestor's data    */
  301.    /* structure. (Should be public memory.)              */
  302.  
  303.    if (unit == AJOYUNIT0) {
  304.  
  305.       UserDataPtr->x = JoyData->unit0.x;
  306.       UserDataPtr->y = JoyData->unit0.y;
  307.  
  308.       if (JoyData->unitflags & U0B1SINGLE) {
  309.          UserDataPtr->button1 = JoyData->unit0.eb1;
  310.          JoyData->unit0.eb1 = 0;
  311.       } else 
  312.          UserDataPtr->button1 = JoyData->unit0.b1;
  313.  
  314.       if (JoyData->unitflags & U0B2SINGLE) {
  315.          UserDataPtr->button2 = JoyData->unit0.eb2;
  316.          JoyData->unit0.eb2 = 0;
  317.       } else 
  318.          UserDataPtr->button2 = JoyData->unit0.b2;
  319.  
  320.       if (JoyData->unitflags & U0B3SINGLE) {
  321.          UserDataPtr->button3 = JoyData->unit0.eb3;
  322.          JoyData->unit0.eb3 = 0;
  323.       } else 
  324.          UserDataPtr->button3 = JoyData->unit0.b3;
  325.  
  326.       if (JoyData->unitflags & U0B4SINGLE) {
  327.          UserDataPtr->button4 = JoyData->unit0.eb4;
  328.          JoyData->unit0.eb4 = 0;
  329.       } else 
  330.          UserDataPtr->button4 = JoyData->unit0.b4;
  331.  
  332.    } else if (unit == AJOYUNIT1) {
  333.  
  334.       UserDataPtr->x = JoyData->unit1.x;
  335.       UserDataPtr->y = JoyData->unit1.y;
  336.  
  337.       if (JoyData->unitflags & U1B1SINGLE) {
  338.          UserDataPtr->button1 = JoyData->unit1.eb1;
  339.          JoyData->unit1.eb1 = 0;
  340.       } else 
  341.          UserDataPtr->button1 = JoyData->unit1.b1;
  342.  
  343.       if (JoyData->unitflags & U1B2SINGLE) {
  344.          UserDataPtr->button2 = JoyData->unit1.eb2;
  345.          JoyData->unit1.eb2 = 0;
  346.       } else 
  347.          UserDataPtr->button2 = JoyData->unit1.b2;
  348.  
  349.       if (JoyData->unitflags & U1B3SINGLE) {
  350.          UserDataPtr->button3 = JoyData->unit1.eb3;
  351.          JoyData->unit1.eb3 = 0;
  352.       } else 
  353.          UserDataPtr->button3 = JoyData->unit1.b3;
  354.  
  355.       if (JoyData->unitflags & U1B4SINGLE) {
  356.          UserDataPtr->button4 = JoyData->unit1.eb4;
  357.          JoyData->unit1.eb4 = 0;
  358.       } else 
  359.          UserDataPtr->button4 = JoyData->unit1.b4;
  360.  
  361.    } else return NULL;  /* Error, not a recognised unit */
  362.  
  363.    /* return success */
  364.  
  365.    return UserDataPtr;
  366.  
  367. }
  368.  
  369. /* End: JoyDriv.c */
  370.